package hostdriver

import (
	"fmt"
	corev1 "gluenet/internal/agent/api/core/v1"
	"net"
	"os"
	"runtime"
	"strings"
	"sync"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/host"
	"github.com/shirou/gopsutil/mem"
)

var (
	currentHost *corev1.Host
	once        sync.Once
)

func GetHost() corev1.Host {
	once.Do(
		func() {
			hostName, err := GetHostName()
			if err != nil {
				panic("get host name err")
			}

			ip, err := GetHostIP()
			if err != nil {
				panic("get host ip err")
			}

			mac, err := GetHostMac()
			if err != nil {
				panic("get host mac err")
			}

			cpus, err := GetCpuCores()
			if err != nil {
				panic("get host cpu err")
			}

			memSize, err := GetMemSize()
			if err != nil {
				panic("get host mem err")
			}

			arch, _ := GetHostArch()

			os, _ := GetHostOS()

			currentHost = &corev1.Host{
				HostName: hostName,
				HostIP:   ip,
				HostMac:  mac,
				CPUCores: cpus,
				MemSize:  memSize,
				Arch:     arch,
				OS:       os,
			}
		})

	return *currentHost
}

func GetHostName() (name string, err error) {
	if name = os.Getenv("HOST_NAME"); name != `` {
		return
	}

	hostInfo, _ := host.Info()
	return hostInfo.Hostname, nil
}

func GetCpuCores() (string, error) {
	count, _ := cpu.Counts(true)
	return fmt.Sprint(count), nil
}

func GetMemSize() (string, error) {
	v, _ := mem.VirtualMemory()
	return fmt.Sprint(v.Total), nil
}

func GetHostIP() (string, error) {
	conn, err := net.Dial("udp", "8.8.8.8:53")
	if err != nil {
		return "", err
	}
	localAddr := conn.LocalAddr().(*net.UDPAddr)
	ip := strings.Split(localAddr.String(), ":")[0]

	return ip, nil
}

func GetHostMac() (string, error) {
	interfaces, err := net.Interfaces()
	if err != nil {
		return "", err
	}
	inter := interfaces[1]
	mac := inter.HardwareAddr.String() //获取本机MAC地址
	return mac, nil
}

func GetHostArch() (string, error) {
	return runtime.GOARCH, nil
}

func GetHostOS() (string, error) {
	return runtime.GOOS, nil
}
